Piece by Piece
Carlo Götz
github.com/c-goetz/jug
mvn com.github.ferstl:depgraph-maven-plugin:aggregate \
"-Dincludes=net.disy*:*:*" -DmergeScopes=trueModulistic terror
A vast sadistic feast
The only way to exit
Is going piece by piece
Slayer, Piece by Piece
frontend und backend jeweils aus dem
Cacheglue relativ kleinfrontend Commits könnten in ~1:30 min gebaut
werdenSNAPSHOT Dependencies sind problematisch
-U Flag würde uns den aktuellsten gebenWir können ja kaum die Ersten sein: auf zu Google!
maven-build-cache-extension
The code currently relies on un-released modifications in the core Maven project,
Idee:
SNAPSHOT Versionen mehr{ Fast, Correct } - Choose two
Wie funktioniert Bazel?
@startuml
skinparam backgroundcolor transparent
skinparam activityFontSize 24
skinparam activityArrowFontSize 24
(*) -->[bazel files] "loading phase"
"loading phase" -->[target graph] "analysis phase"
"analysis phase" -->[action graph] "execution phase"
"execution phase" -->[built files] (*)
@enduml
java_binaryplantumlbazel run //:plantumldef _plantuml_impl(ctx):
src = ctx.file.src
filename = src.basename[:-len(src.extension)-1]
out = ctx.actions.declare_file(filename + ".png")
ctx.actions.run(
mnemonic = "plantuml",
executable = ctx.executable._tool,
arguments = ["-tpng", "-o", out.dirname, src.path],
inputs = [ctx.file.src],
outputs = [out],
)
return [
DefaultInfo(files = depset([out]))
]load("plantuml.bzl", "plantuml")
plantuml(
name = "phases",
src = "phases.puml",
)
bazel build //:phasesopen bazel-bin/phases.pngplantuml
├── bazel-bin -> EXECROOT/bazel-out/k8-fastbuild/bin
├── bazel-example -> EXECROOT
├── bazel-out -> EXECROOT/bazel-out
├── bazel-testlogs -> EXECROOT/bazel-out/k8-fastbuild/testlogs
├── BUILD
├── plantuml.bzl
├── phases.puml
└── WORKSPACE
EXECROOT=~/.cache/bazel/_bazel_goetz/e8d693d10d07eed0b18daaa2a2cce0b5/execroot/example
bazel build //:phases \
-s \ # show subcommand
--sandbox_debug # show sandbox commands, preserve sandboxSubcommand:
SUBCOMMAND: # //:phases [action 'plantuml phases.png', configuration: <hash>, execution platform: @local_config_platform//:host]
(cd /home/goetz/.cache/bazel/_bazel_goetz/<hash>/execroot/example && \
exec env - \
bazel-out/host/bin/plantuml -tpng -o bazel-out/k8-fastbuild/bin phases.puml)
...
linux-sandbox-pid1.cc:371: remount ro: /
linux-sandbox-pid1.cc:371: remount ro: /dev
linux-sandbox-pid1.cc:371: remount rw: /dev/shm
...
linux-sandbox-pid1.cc:371: remount rw: <output base>/sandbox/linux-sandbox/4/execroot/example
example
├── bazel-out
└── phases.puml -> <exec root>/phases.puml
mvn verify -Dmaven.repo.local=./repoKleines Tool
def _mvn_external_deps_impl(ctx):
mvn = [ "mvn", "verify", "-Dmaven.repo.local=./repo" ]
mvn_result = ctx.execute(mvn)
# error handling
# find -exec sed: set timestamps in mvn metadata
ctx.file(
"BUILD",
"""
package(default_visibility = ["//visibility:public"])
filegroup(
name = "deps",
srcs = glob(["repo/**"], ["**/net/disy/cadenza/**"]),
)""",
)mvn_external_deps(
name = "mvn-external",
lock_file = "//:lock-file.txt",
parent_pom = "//:Maven_Parent/pom.xml",
maven_settings = "//:tools/maven-settings.xml",
)
bazel run //tools/bazel-gen:bazel-gen -- \
lock-file Maven_Parent/pom.xml lock-file.txt
bazel build @mvn-external//:depsmvn-externalmvn_multi_module = rule(
implementation = _mvn_multi_module_impl,
attrs = {
"srcs": attr.label_list(),
"deps": attr.label_list(),
"modules": attr.string_list(),
},
)srcs Inhalte der einzelnen Moduledeps für Backend und Frontend jeweils
mvn-external
modules welche Module werden gebaut?mvn_multi_module(
name = "frontend",
srcs = glob(
["Cadenza_Web_Frontend/**"],
[
"Cadenza_Web_Frontend/target",
"Cadenza_Web_Frontend/node_modules",
]
),
deps = ["@mvn-external//:deps"],
modules = ["<dir>:<group_id>:<artifact_id>:<extensions>"],
)def _mvn_multi_module_impl(ctx):
modules = [_parse_module(m) for m in ctx.attr.modules]
out_files = [_out_files(ctx, m) for m in modules]
module_list = _module_list(modules)
local_repo_path = _link_deps(ctx)
ctx.actions.run_shell(
# ...
)
local_repo_files = local_repo_files(modules)
return [
DefaultInfo(files = depset(out_files)),
LocalRepoArtifactInfo(files = depset(local_repo_files)),
]dir: FS Pfadclassifiers_extensions
".jar""-frontend.zip"LocalRepoFileInfos erstellt werdenLocalRepoFileInfo Zielpfad aus Maven CoordinatesDefaultInfo
mvn-external seinmvn_multi_modulebazel run //tools/bazel-gen:bazel-gen -- \
lock-file Maven_Parent/pom.xml lock-file.txt
bazel run //tools/bazel-gen:bazel-gen -- \
generate Maven_Parent/pom.xml BUILD
bazel build //:glue.bazelrc
# maven logs are huge
build --experimental_ui_max_stdouterr_bytes=4000000
# use remote cache
build --remote_cache=grpcs://bazel-grpc.<cluster-url>
# don't upload by default, override for CI
build --remote_upload_local_results=false0 Sekunden Builds auf CI?
source,
build--output_base=buildbuildWie eleminieren wir den Maven Local Repo Build?
–> Wir entfernen Maven (fast) aus dem Build
switch (node.getNodeName()) {
case "sourceDirectory":
json.sourceDirectory = node.getTextContent();
break;
case "outputDirectory": /*do nothing*/ break;
case "pakkage":
json.packageFqn = node.getTextContent();
break;
case "comment":
json.comment = node.getTextContent();
break;
default:
throw new IllegalStateException("can't handle: "
+ node.getNodeName());
}stdin/outSystem.setOut/In/Err()
Courtesy of xjc
jvm_flags = ["-agentlib:jdwp..."]mvn -X für classpathmvnDebugstraceunpack-dependency, JVM Args für surefire, …Beispiel: dependency:analyze
.bazelrc:
build --strict_java_deps warnrules_jvm_external
Ruft mehrere Rules auf.
for i, xjc in enumerate(xjcs):
xjc_sources(
name = name + "_xjc_" + str(i),
srcs = native.glob(xjc.includes),
)
native.java_library(
name = name + "_jar",
srcs = native.glob(
[directory + "/src/main/java/**/*.java"],
[directory + "**/module-info.java"],
),
)
test_srcs = native.glob("""...""")
if len(test_srcs) > 0:
# ...WORKSPACE und BUILD werden generiert
bazel run //tools/bazel-gen:bazel-gen -- gen
bazel test --test_tag_filters=small -- \
//... -//tools/...
bazel run //tools/bazel-gen:bazel-gen -- clean
Kompiliert aber Test Fehler…
test_data
target/test-classes vs. foo_tests.jar
getClass().getResourceAsStream()new File(getClass().getResources().getPath())rules_js von aspect-build{@link ...}: rewrite
generated classesBasicFileAttributeView.setTimes()--execution_log_json_file=/tmp/exec(date "+%T").log
--bes_results_url=https://... --bes_backend=grpcs://...
Frontend, diverse Test Jobs
Vielen Dank für eure Aufmerksamkeit!
Vielen Dank an Boris, Viktorija, Simon und Nicolai für Support, Vertrauen und Budget!